﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using BinaryAnalysis.UnidecodeSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using NHibernate;
using Studentium.Entities;

namespace Studentium.Util
{
    class ReportGenerator
    {
        public static void GenerateFinishingStudents(ISession session)
        {
            IList studentsIds = session.CreateSQLQuery("SELECT id FROM student WHERE"
+ " ("
+ "   SELECT SUM(ClassesNumber) as classesNum FROM payment WHERE payment.studentId = student.Id"
+ " )"
+ " -"
+ " ("
+ "   SELECT COUNT(*) FROM classattendance c"
+ "   WHERE c.studentId = student.id AND Status <> 2"
+ "   AND"
+ "   ("
+ "     SELECT COUNT(*) FROM calendarentry calendar"
+ "     WHERE c.calendarEntryId=calendar.EntryId AND upper(calendar.Description)<>'DRAMA'"
+ "           AND upper(calendar.Description)<>'MOVIE'"
+ "   ) = 1"
+ " )"
+ " <=2").List();
            var document = new Document(PageSize.LETTER);
            string shortDateString = DateTime.Now.ToShortDateString().Replace(@"\", "-").Replace("/", "-");
            var reportName = "Finishing students on " + shortDateString;
            if (File.Exists(reportName + ".pdf"))
            {
                int number = 1;
                while (File.Exists(reportName + "_" + number + ".pdf"))
                    number++;
                reportName += "_" + number + ".pdf";
            }
            else
                reportName += ".pdf";

            PdfWriter.GetInstance(document, new FileStream(reportName, FileMode.Create));
            BaseFont bf = BaseFont.CreateFont("Resources/arial.ttf", System.Text.Encoding.GetEncoding("KOI8-U").BodyName, true);
            Font font = new Font(bf, 8);
            document.Open();
            document.Add(new Paragraph("Finishing students on " + shortDateString));
            document.Add(new Paragraph("Students with less than 2 prepaid classes which going to attend some class today:"));
            bool willBeSomeoneToday = false;
            foreach (var id in studentsIds)
            {
                var student = session.Load<Student>(id);
                if (!student.Classes.Any(attendance => AreSameDay(attendance.CalendarEntry.Date, DateTime.Now)) || student.Finished)
                    continue;
                willBeSomeoneToday = true;
                var title = new Paragraph(student.FullName + "    " + (student.CalcBoughtClasses() - student.CalcWastedClasses()), font);
                //title.SetAlignment("Center");
                document.Add(title);
                //document.Add(new Phrase(comic.Description));
                //document.Add(Chunk.NEXTPAGE);
            }
            if (!willBeSomeoneToday)
                document.Add(new Paragraph("None.", font));
            document.Add(new Paragraph("___________________________________________________________"));
            document.Add(new Paragraph("Other students with less than 2 prepaid lessons:"));
            foreach (var id in studentsIds)
            {
                var student = session.Load<Student>(id);
                if (student.Classes.Any(attendance => AreSameDay(attendance.CalendarEntry.Date, DateTime.Now)) || student.Finished)
                    continue;
                int maxLength = Math.Max(30, student.FullName.Length);
                string blankSpace = Enumerable.Repeat(" ", 2 * (maxLength + 1 - student.FullName.Length)).Aggregate((result, x) => result + x);
                var title = new Paragraph(student.FullName + blankSpace
                                           + (student.CalcBoughtClasses() - student.CalcWastedClasses()), font);
                document.Add(title);
            }
            document.Close();
            Process.Start(reportName);
        }

        private static bool AreSameDay(DateTime date1, DateTime date2)
        {
            return date1.Year == date2.Year && date1.DayOfYear == date2.DayOfYear;
        }

        public static void GenerateCurriculum(ISession session, DateTime dateOfCurriculum)
        {
            var query = "SELECT studentId, Date, Description, Status, calendar.Level FROM classattendance as attendence "
                        + " LEFT JOIN calendarentry as calendar ON calendar.EntryId=attendence.calendarEntryId "
                        + " WHERE DATE(calendar.Date) = DATE('" + dateOfCurriculum.ToString("yyyy-MM-dd") +
                        "') ORDER BY Date, Description, calendar.Level";
            IList attendences = session.CreateSQLQuery(query).List();
            var document = new Document(PageSize.LETTER);
            var reportName = "Curriculum on " + dateOfCurriculum.ToString("dd.MM.yyyy");
            if (File.Exists(reportName + ".pdf"))
            {
                int number = 1;
                while (File.Exists(reportName + "_" + number + ".pdf"))
                    number++;
                reportName += "_" + number + ".pdf";
            }
            else
                reportName += ".pdf";

            PdfWriter.GetInstance(document, new FileStream(reportName, FileMode.Create));
            BaseFont bf = BaseFont.CreateFont("Resources/arial.ttf", System.Text.Encoding.GetEncoding("KOI8-U").BodyName, true);
            Font font = new Font(bf, 8);
            document.Open();
            document.Add(new Paragraph("Curriculum on " + dateOfCurriculum.ToString("dd.MM.yyyy")));

            string previousClass = "";
            foreach (var attendence in attendences)
            {
                object[] attendenceData = ((object[]) attendence);
                var student = session.Load<Student>(attendenceData[0]);
                var studentName = ToLatin(student.FullName);                
                DateTime date = (DateTime)attendenceData[1];
                AttendenceStatus status = (AttendenceStatus)attendenceData[3];                
                var title = new Paragraph(date.ToShortTimeString() + " " + attendenceData[2] + " " + (StudentLevel)attendenceData[4] +  " " + status + " " + studentName, font);
                if (previousClass != date.ToShortTimeString() + " " + attendenceData[2] + " " + attendenceData[4])
                {
                    document.Add(new Paragraph("______________________________________________"));
                    previousClass = date.ToShortTimeString() + " " + attendenceData[2] + " " + attendenceData[4];
                }

                document.Add(title);
            }
            document.Close();
            Process.Start(reportName);
        }

        private static string ToLatin(string s)
        {
            return s.Unidecode();
        }
    }
}